package com.xmmj.baselibrary.utils.viewadapter.recyclerview

import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
import com.xmmj.baselibrary.utils.adapter.recyclerview.INoDataView
import com.xmmj.baselibrary.utils.adapter.recyclerview.WithEmptyViewBindingAdapter
import com.xmmj.baselibrary.widget.RecyclerViewPageChangeListener
import me.tatarka.bindingcollectionadapter2.ItemBinding
import me.tatarka.bindingcollectionadapter2.collections.AsyncDiffObservableList
import me.tatarka.bindingcollectionadapter2.recyclerview.R

@BindingAdapter(
    value = ["itemBinding", "items", "adapter", "itemIds", "viewHolder", "diffConfig", "emptyView", "showEmpty"],
    requireAll = false
)
fun <T> setAdapter(
    recyclerView: RecyclerView,
    itemBinding: ItemBinding<in T>?,
    items: List<T>?,
    adapter: WithEmptyViewBindingAdapter<T>?,
    itemIds: WithEmptyViewBindingAdapter.ItemIds<in T>?,
    viewHolderFactory: WithEmptyViewBindingAdapter.ViewHolderFactory?,
    diffConfig: AsyncDifferConfig<T>?,
    emptyView: INoDataView?,
    showEmpty: Boolean
) {
    if (itemBinding != null) {
        var adapter2 = adapter
        val oldAdapter = recyclerView.adapter
        if (adapter2 == null) {
            adapter2 = if (oldAdapter == null) {
                WithEmptyViewBindingAdapter()
            } else {
                if (oldAdapter is WithEmptyViewBindingAdapter<*>) {
                    oldAdapter as WithEmptyViewBindingAdapter<T>
                } else {
                    return
                }
            }
        }
        adapter2.itemBinding = itemBinding
        if (diffConfig != null && items != null) {
            var list: AsyncDiffObservableList<T>? =
                recyclerView.getTag(R.id.bindingcollectiondapter_list_id) as AsyncDiffObservableList<T>
            if (list == null) {
                list = AsyncDiffObservableList(diffConfig)
                recyclerView.setTag(R.id.bindingcollectiondapter_list_id, list)
                adapter2.setItems(list)
            }
            list.update(items)
        } else {
            adapter2.setItems(items)
        }
        adapter2.setItemIds(itemIds)

        adapter2.setViewHolderFactory(viewHolderFactory)
        adapter2.isEnableShowEmptyView = showEmpty
        if (emptyView?.view != null) {
            adapter2.setEmptyView(emptyView)
        }
        if (oldAdapter !== adapter2) {
            recyclerView.adapter = adapter2
        }
    } else {
        recyclerView.adapter = null
    }
}

@BindingAdapter(value = ["itemDecoration", "layoutManager"], requireAll = false)
fun setParams(
    recyclerView: RecyclerView,
    layoutManager: RecyclerView.LayoutManager,
    itemDecoration: ItemDecoration
) {
    layoutManager.let {
        recyclerView.layoutManager = layoutManager
    }

    itemDecoration.let {
        recyclerView.addItemDecoration(itemDecoration)
    }
}

@BindingAdapter(value = ["smoothScrollToPosition"], requireAll = false)
fun smoothScrollToPosition(recyclerView: RecyclerView, smoothScrollToPosition: Int) {
    recyclerView.smoothScrollToPosition(smoothScrollToPosition)
}

@BindingAdapter(value = ["scrollToPosition"], requireAll = false)
fun scrollToPosition(recyclerView: RecyclerView, scrollToPosition: Int) {
    recyclerView.scrollToPosition(scrollToPosition)
}

@BindingAdapter(value = ["scrollToPositionWithOffset", "offset"], requireAll = false)
fun scrollToPositionWithOffset(
    recyclerView: RecyclerView,
    scrollToPositionWithOffset: Int,
    offset: Int
) {
    if (recyclerView.layoutManager is LinearLayoutManager) {
        (recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
            scrollToPositionWithOffset,
            offset
        )
    }
}

@BindingAdapter(value = ["onScrollListener"], requireAll = false)
fun addOnScrollListener(
    recyclerView: RecyclerView,
    onScrollListener: RecyclerView.OnScrollListener
) {
    onScrollListener.let {
        recyclerView.addOnScrollListener(it)
    }
}

@BindingAdapter(value = ["onViewPageChangeListener"], requireAll = false)
fun setOnViewPageChangeListener(
    recyclerView: RecyclerView,
    onViewPageChangeListener: RecyclerViewPageChangeListener
) {
    onViewPageChangeListener.let {
        it.SnapHelper().attachToRecyclerView(recyclerView)
        recyclerView.addOnScrollListener(it)
    }
}